package com.itheima.user.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.article.feign.ApAuthorFeign;
import com.itheima.article.pojo.ApAuthor;
import com.itheima.common.constants.BusinessConstants;
import com.itheima.common.enums.HttpCodeEnum;
import com.itheima.common.exception.LeadNewsException;
import com.itheima.common.vo.PageResultVo;
import com.itheima.common.vo.ResultVo;
import com.itheima.user.dto.ApUserRealnamePageRequestDto;
import com.itheima.user.mapper.ApUserMapper;
import com.itheima.user.mapper.ApUserRealnameMapper;
import com.itheima.user.pojo.ApUser;
import com.itheima.user.pojo.ApUserRealname;
import com.itheima.user.service.ApUserRealnameService;
import com.itheima.wemedia.feign.WmUserFeign;
import com.itheima.wemedia.pojo.WmUser;
import com.mysql.cj.xdevapi.AddResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.Map;

/**
 * @version 1.0
 * @description <p>APP实名认证信息 业务实现</p>
 * @package com.itheima.user.service.impl
 */
@Service
@Slf4j
public class ApUserRealnameServiceImpl extends ServiceImpl<ApUserRealnameMapper, ApUserRealname> implements ApUserRealnameService {

    @Autowired
    private ApUserMapper apUserMapper;

    @Autowired
    private WmUserFeign wmUserFeign;

    @Autowired
    private ApAuthorFeign apAuthorFeign;

    /**
     * 分页查询
     *
     * @param dto
     * @return
     */
    @Override
    public PageResultVo findPage(ApUserRealnamePageRequestDto dto) {
        //1. 分页参数
        Page<ApUserRealname> pageInfo = new Page(dto.getPage(), dto.getSize());
        //2. 构建条件
        LambdaQueryWrapper<ApUserRealname> lqw = new LambdaQueryWrapper<>();
        lqw.eq(null != dto.getStatus(), ApUserRealname::getStatus, dto.getStatus());
        //3. 分页查询
        page(pageInfo, lqw);
        //4. 构建分页结果
        return PageResultVo.pageResult(dto.getPage(), dto.getSize(), pageInfo.getTotal(), pageInfo.getRecords());
    }

    /**
     * 实名认证审核-驳回
     *
     * @param paramMap
     */
    @Override
    public void authFail(Map<String, Object> paramMap) {
        //更新ap_user_realname
        //status=2 审核失败
        //updated_time=更新时间
        //reason=原因
        //条件id=?
        //update ap_user_realname set status=2,updated_time=?,reason=? where id=?

        //1. 参数校验
        Integer id = (Integer) paramMap.get("id");
        String msg = (String) paramMap.get("msg");
        if (null == id || StringUtils.isEmpty(msg)) {
            throw new LeadNewsException(HttpCodeEnum.PARAM_INVALID);
        }
        //2. 构建更新对象
        ApUserRealname apUserRealname = new ApUserRealname();
        apUserRealname.setUpdatedTime(LocalDateTime.now());
        apUserRealname.setStatus(BusinessConstants.ApUserRealnameConstants.AUTH_CREATING);
        apUserRealname.setReason(msg);
        apUserRealname.setId(id.longValue());

        //3. 执行更新
        updateById(apUserRealname);

    }

    /**
     * 实名认证审核-通过
     *
     * @param paramMap
     */
    @Override
    @Transactional
    public void authPass(Map<String, Object> paramMap) {
        // 此id为实名认证表中的记录的id，并不是用户id
        Integer id = (Integer) paramMap.get("id");
        if (null == id) {
            throw new LeadNewsException(HttpCodeEnum.PARAM_INVALID);
        }
        // 查询用户信息
        ApUserRealname userRealname = getById(id);
        if (userRealname.getStatus() != BusinessConstants.ApUserRealnameConstants.AUTH_WAITING) {
            throw new LeadNewsException("实名认证记录状态不正确!");
        }

        //1. 更新实名认证记录的状态,
        updateUserRealnameStatusPass(id);


        // userId=app用户的id
        Long userId = userRealname.getUserId();

        // 查询ap_user表
        ApUser apUser = apUserMapper.selectById(userId);

        //2. 添加自媒体人账号
        Long wmUser = addWmUser(apUser);

        //3. 添加作者账号
        addApAuthor(apUser, wmUser);

        //4. 更新用户的flag标识为自自媒体人
        updateUserFlag(userId);

    }

    /**
     * 更新apUser的flag标记为自媒体人
     *
     * @param userId
     */
    private void updateUserFlag(Long userId) {
        ApUser apUser = new ApUser();
        apUser.setId(userId);
        apUser.setFlag(BusinessConstants.ApUserConstants.FLAG_WEMEDIA);
        apUserMapper.updateById(apUser);
    }

    /**
     * 添加作者账号
     *
     * @param apUser
     * @param wmUserId
     */
    private void addApAuthor(ApUser apUser, Long wmUserId) {
        //1. 通过apUserId, wmUserId查询作者是否已经存在
        ResultVo<ApAuthor> getResult = apAuthorFeign.getByApUserAndWmUserId(apUser.getId(), wmUserId);
        //1.1 解析结果，失败则报错
        log.debug("远程调用文章微服务添加作者:{},{},{}", apUser.getId(), wmUserId, JSON.toJSON(getResult));
        if (!getResult.isSuccess()) {
            throw new LeadNewsException("远程调用文章微服务查询失败!");

        }

        //2. 判断作者是否存在， 如果不存在则添加作者
        ApAuthor apAuthor = getResult.getData();
        if (null == apAuthor) {
            apAuthor = new ApAuthor();
            apAuthor.setCreatedTime(LocalDateTime.now());
            apAuthor.setType(BusinessConstants.ApAuthorConstants.A_MEDIA_USER);
            apAuthor.setName(apUser.getName());
            apAuthor.setUserId(apUser.getId());
            apAuthor.setWmUserId(wmUserId);
            ResultVo addResult = apAuthorFeign.addApAuthor(apAuthor);
            log.debug("远程调用文章微服务添加作者:{},{},{}", apUser.getId(), wmUserId, JSON.toJSON(addResult));


            //3. 解析结果，失败则报错
            if (!addResult.isSuccess()) {
                log.debug("远程调用文章微服务添加作者失败,{},{},{}", apUser.getId(), wmUserId, getResult.getErrorMessage());
                throw new LeadNewsException("远程调用文章微服务添加作者失败!");
            }
        }
    }

    /**
     * 添加自媒体人账号
     *
     * @param apUser
     * @return 返回自媒体用户id
     */
    private Long addWmUser(ApUser apUser) {
        //1. 判断是否已经添加过自媒体人了

        //1.1 通过ap_user_id查询 wm_user表 属于自媒体微服，远程调用自媒体
        ResultVo<WmUser> getByResult = wmUserFeign.getByApUserId(apUser.getId());
        log.debug("自媒体人账号apUserId:{}", apUser.getId());

        //1.2 解析返回结果，失败抛异常
        if (!getByResult.isSuccess()) {
            log.error("远程调用微服务查询失败!{},{}", apUser.getId(), getByResult.getErrorMessage());
            throw new LeadNewsException("远程调用微服务查询失败!");
        }

        //1.3 有数据则代表已经创建过了, 返回自媒体用户id
        WmUser wmUser = getByResult.getData();
        log.debug("自媒体人账号apUserId:{}.wmUserId:{}", apUser.getId(), null == wmUser ? "不存在" : wmUser.getId());
        if (null != wmUser) {
            return wmUser.getId();
        }

        //2. 如果没有添加则要创建自媒体人
        //2.1 创建WmUser对象, 给属性赋值
        wmUser = new WmUser();
        // 复制属性，类中的属性名称及类型如果相同才会复制
        BeanUtils.copyProperties(apUser, wmUser);

        // 此id为app_user_id，不能作自媒体的wm_user表中的id
        wmUser.setId(null);


        // 状态不一致
        if (apUser.getStatus() != BusinessConstants.ApUserConstants.STATUS_LOCK) {
            wmUser.setStatus(BusinessConstants.WmUserConstants.STATUS_OK);

        } else {
            wmUser.setStatus(BusinessConstants.WmUserConstants.STATUS_LOCKED);

        }
        wmUser.setApUserId(apUser.getId());
        wmUser.setNickname(wmUser.getName());
        wmUser.setType(BusinessConstants.WmUserConstants.TYPE_PERSONAL);
        wmUser.setScore(0);
        wmUser.setCreatedTime(LocalDateTime.now());

        //2.2 远程调用自媒体，添加
        ResultVo<WmUser> addResult = wmUserFeign.addWmUser(wmUser);
        //2.3 解析结果，失败抛异常
        if (!addResult.isSuccess()) {
            log.debug("远程调用微服务添加失败,{},{}", apUser.getId(), getByResult.getErrorMessage());
            throw new LeadNewsException("远程调用微服务添加失败!");
        }
        WmUser data = addResult.getData();
        log.debug("自媒体账号apUserId:{},wmUserId{}  添加成功", apUser.getId(), data.getId());

        //为什么不能使用wmUser.getId来返回?
        return data.getId();

    }

    /**
     * 更新实名认证记录的状态为成功
     *
     * @param id
     */
    private void updateUserRealnameStatusPass(Integer id) {
        //2. 构建更新对象
        ApUserRealname apUserRealname = new ApUserRealname();
        apUserRealname.setUpdatedTime(LocalDateTime.now());
        apUserRealname.setStatus(BusinessConstants.ApUserRealnameConstants.AUTH_PASS);
        apUserRealname.setId(id.longValue());
        //3. 执行更新
        updateById(apUserRealname);

    }
}
